package com.mh.service.impl;

import com.mh.dto.R;
import com.mh.dto.bo.UseCouponBo;
import com.mh.dto.vo.UseCouponRecordVo;
import com.mh.pojo.CouponInfos;
import com.mh.pojo.CouponUse;
import com.mh.pojo.GoodsInfos;
import com.mh.pojo.UserInfos;
import com.mh.service.CouponService;
import com.mongodb.client.result.UpdateResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Date:2024/11/2
 * author:zmh
 * description: 优惠券相关接口
 **/

@Service
@RequiredArgsConstructor
@Slf4j
public class CouponServiceImpl implements CouponService {

    private final MongoTemplate  mongoTemplate;

    private final RabbitTemplate  rabbitTemplate;

    /**
     * 创建优惠券
     * @param couponInfos 优惠券信息
     * @return ·
     */
    @Override
    public R<String> createCoupon(CouponInfos couponInfos) {
        CouponInfos save = mongoTemplate.save(couponInfos);
        return R.success("优惠券惠券创建成功");
    }

    /**
     * 获取商家所有优惠券信息
     * @param storeId 商家id
     * @return ·
     */
    @Override
    public R<List<CouponInfos>> getCouponInfosByStoreId(String storeId) {
        Query query = new Query().addCriteria(Criteria.where("bindStore").is(storeId));
        List<CouponInfos> couponInfos = mongoTemplate.find(query, CouponInfos.class);
        return R.success(couponInfos);
    }

    /**
     * 用户领取优惠券
     * @param userId 用户ID
     * @param couponId 优惠券ID
     * @return ·
     */
    @Override
    public R<String> userGetCoupon(String userId, String couponId) {
        // 获取用户信息
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        Update update = new Update();
        UserInfos userInfos = mongoTemplate.findOne(query, UserInfos.class);

        // 获取出用户的优惠券列表
        List<UserInfos.Coupon> coupons = userInfos.getCoupons();
        // 鉴空，如果为空就初始化添加且设置数量为1，否则仅需要添加优惠券数量+1
        if (coupons.isEmpty()) {
            UserInfos.Coupon coupon = new UserInfos.Coupon();
            coupon.setCouponId(couponId);
            coupon.setNumber(1);
            coupons.add(coupon);
            update.set("coupons", coupons);
            mongoTemplate.updateFirst(query, update, UserInfos.class);
            return R.success("优惠券领取成功");
        }

        for (UserInfos.Coupon coupon : coupons) {
            if (coupon.getCouponId().equals(couponId)) {
                coupon.setNumber(coupon.getNumber() + 1);
                update.set("coupons", coupons);
                mongoTemplate.updateFirst(query, update, UserInfos.class);
                return R.success("优惠券领取成功");
            }
        }

        // 如果用户没有该优惠券，则添加该优惠券
        UserInfos.Coupon coupon = new UserInfos.Coupon();
        coupon.setCouponId(couponId);
        coupon.setNumber(1);
        coupons.add(coupon);
        update.set("coupons", coupons);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserInfos.class);

        if (updateResult.wasAcknowledged()) {
            return R.success("优惠券领取成功");
        }

        return R.error("优惠券领取失败o.0");
    }

    /**
     * 获取用户所有优惠券信息
     * @param userId 用户ID
     * @return ·
     */
    @Override
    public R<List<CouponInfos>> getCouponInfosByUserId(String userId) {
        // 取出用户信息中的所有优惠券信息
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        UserInfos userInfos = mongoTemplate.findOne(query, UserInfos.class);
        List<UserInfos.Coupon> coupons = userInfos.getCoupons();
        if(coupons.isEmpty()){
            return R.error("用户没有优惠券");
        }

        // 遍历取出所有优惠券ID存储为列表，再批量查询优惠券信息
        ArrayList<String> couponIds = new ArrayList<>();
        for (UserInfos.Coupon coupon : coupons) {
            couponIds.add(coupon.getCouponId());
        }

        // 取出所有包含ID的优惠券信息
        Query query1 = new Query().addCriteria(Criteria.where("couponId").in(couponIds));
        List<CouponInfos> couponInfos = mongoTemplate.find(query1, CouponInfos.class);
        return R.success(couponInfos);
    }

    /**
     * 获取下单商品时用户可用优惠券信息
     * @param userId 用户ID
     * @param goodsId 商品ID
     * @return ·
     */
    @Override
    public R<List<CouponInfos>> getUseAbleCouponInfosByUserId(String userId, String goodsId) {
        // 获取用户拥有的优惠券
        R<List<CouponInfos>> couponInfosByUserId = getCouponInfosByUserId(userId);
        List<CouponInfos> couponInfos = couponInfosByUserId.getData();

        // 获取商品所属店铺ID
        Query query = new Query().addCriteria(Criteria.where("goodsId").is(goodsId));
        GoodsInfos goodsInfos = mongoTemplate.findOne(query, GoodsInfos.class);
        String ownerStoreId = goodsInfos.getOwnerStoreId();

        // 遍历用户所有优惠券，取出可用的优惠券
        ArrayList<CouponInfos> couponInfos1 = new ArrayList<>();
        for (CouponInfos couponInfo : couponInfos) {
            if (couponInfo.getBindStore().equals(ownerStoreId)) {
                couponInfos1.add(couponInfo);
            }
        }
        if(couponInfos1.isEmpty()){
            return R.error("没有可用的优惠券");
        }

        return R.success(couponInfos1);
    }

    /**
     * 用户使用优惠券
     * @param userId 用户ID
     * @param couponId 优惠券ID
     * @return ·
     */
    @Override
    public R<String> useCoupon(String userId, String couponId) {
        // 取出用户所有的优惠券信息
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        UserInfos userInfos = mongoTemplate.findOne(query, UserInfos.class);
        List<UserInfos.Coupon> coupons = userInfos.getCoupons();

        Update update = new Update();

        // 遍历用户所有的优惠券，取出要使用的优惠券，数量-1
        for (UserInfos.Coupon coupon : coupons) {
            if (coupon.getCouponId().equals(couponId) && coupon.getNumber() > 1) {
                coupon.setNumber(coupon.getNumber() - 1);
                update.set("coupons", coupons);
                mongoTemplate.updateFirst(query, update, UserInfos.class);
                // 通知RabbitMQ创建优惠券使用记录
                rabbitTemplate.convertAndSend("useCoupon",new UseCouponBo(userId,couponId));
                return R.success("优惠券使用成功");
            }
            if (coupon.getCouponId().equals(couponId) && coupon.getNumber() == 1) {
                coupons.remove(coupon);
                update.set("coupons", coupons);
                mongoTemplate.updateFirst(query, update, UserInfos.class);
                // 通知RabbitMQ创建优惠券使用记录
                rabbitTemplate.convertAndSend("useCoupon",new UseCouponBo(userId,couponId));
                return R.success("优惠券使用成功");
            }
        }
        return R.error("优惠券使用失败o.0");
    }

    /**
     * 获取用户使用优惠券记录
     * @param userId 用户ID
     * @return ·
     */
    @Override
    public R<List<UseCouponRecordVo>> getUseCouponRecordByUserId(String userId) {
        // 根据用户ID取出该用户使用优惠券的记录
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        List<CouponUse> couponUses = mongoTemplate.find(query, CouponUse.class);

        if(couponUses.size() == 0){
            return R.error("用户没有使用过优惠券");
        }

        // 遍历使用记录，查询出优惠券信息构造DTO对象列表返回
        ArrayList<UseCouponRecordVo> useCouponRecordVos = new ArrayList<>();
        for (CouponUse couponUs : couponUses) {
            UseCouponRecordVo tempVo = new UseCouponRecordVo();
            Query query1 = new Query().addCriteria(Criteria.where("couponId").is(couponUs.getCouponId()));
            CouponInfos couponInfo = mongoTemplate.findOne(query1, CouponInfos.class);

            if(couponInfo == null){
                continue;
            }

            // 拷贝优惠券信息和使用时间
            BeanUtils.copyProperties(couponInfo, tempVo);
            tempVo.setUseTime(couponUs.getUseTime());

            useCouponRecordVos.add(tempVo);
        }

        return R.success(useCouponRecordVos);
    }

    /**
     * 用户是否领取过优惠券
     * @param userId 用户ID
     * @param couponId 优惠券ID
     * @return ·
     */
    @Override
    public R<Boolean> checkIsGetByUserIdAndCouponId(String userId, String couponId) {
        // 获取出用户所有优惠券信息
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
        UserInfos userInfos = mongoTemplate.findOne(query, UserInfos.class);

        // 取出用户所有的优惠券
        List<UserInfos.Coupon> coupons = userInfos.getCoupons();
        if(coupons.isEmpty()){
            return R.error("用户没有优惠券");
        }

        for (UserInfos.Coupon coupon : coupons) {
            if (coupon.getCouponId().equals(couponId)) {
                return R.success(true); // 领取过
            }
        }
        return R.success(false); // 未领取
    }
}
